﻿/******************************************************************************
	Copyright 2005-2007 R2@DevFx.NET 
	DevFx.NET is free software; you can redistribute it and/or modify
	it under the terms of the Lesser GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	DevFx.NET is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	Lesser GNU General Public License for more details.

	You should have received a copy of the Lesser GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
/*******************************************************************************/

using System;
using System.Collections.Generic;
using System.Security.Permissions;
using HTB.DevFx.Core;
using HTB.DevFx.Utils;

namespace HTB.DevFx.Security
{
	/// <summary>
	/// 权限拦截属性
	/// </summary>
	/// <remarks>
	///	用于需要权限判断的地方
	/// </remarks>
	/// <example>
	/// 示例参见<see cref="Authorization"/>
	/// </example>
	[Serializable, AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
	public class PermissionInterceptorAttribute : InterceptorAttribute
	{
		/// <summary>
		/// 构造方法（为安全机制调用）
		/// </summary>
		/// <param name="action">拦截动作</param>
		protected PermissionInterceptorAttribute(SecurityAction action) : base(action) {}

		/// <summary>
		/// 构造方法
		/// </summary>
		/// <param name="action">拦截动作，目前只有<see cref="InterceptorAction.Demand"/></param>
		public PermissionInterceptorAttribute(InterceptorAction action) : base(action) {
		}

		/// <summary>
		/// 获取/设置权限编号
		/// </summary>
		public string PermissionNo { get; set; }

		/// <summary>
		/// 获取/设置权限名称
		/// </summary>
		public string Title { get; set; }

		/// <summary>
		/// 拦截执行的方法
		/// </summary>
		protected override void Demand() {
			Demand(this, true);
		}

		/// <summary>
		/// 拦截执行的方法
		/// </summary>
		internal static IAOPResult Demand(PermissionInterceptorAttribute interceptorAttribute, bool throwErrorOnFailed) {
			var ps = new List<string>();
			if (interceptorAttribute != null) {
				var pn = interceptorAttribute.PermissionNo;
				if (!string.IsNullOrEmpty(pn)) {
					ps.Add(pn);
				}
			}
			var permissions = TypeHelper.GetAttributeFromRuntimeStack<PermissionAttribute>(false);
			if (permissions != null && permissions.Length > 0) {
				for (var i = 0; i < permissions.Length; i++) {
					var pn = permissions[i].PermissionNo;
					if (!string.IsNullOrEmpty(pn)) {
						ps.Add(pn);
					}
				}
			}
			IAOPResult result = new AOPResult(0);
			if (ps.Count > 0) {
				result = Securitor.Authorization.Authorize(ps.ToArray());
				if (result.IsFailed) {
					if (throwErrorOnFailed) {
						throw new SecurityAuditException(result.ResultNo, result.ResultDescription, true, null);
					}
				}
			}
			return result;
		}
	}
}
